#pragma once
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;

#define PAtH "./fifo.txt"
#define MODE 0666
class FIFO // 管理fifo的创建与销毁
{
public:
    FIFO(string path)
        : _path(path)
    {
        int n = mkfifo(_path.c_str(), MODE); // 创建，成功返回0
        if (n == 0)
        {
            cout << "name_pipe creat success..." << endl;
        }
        else
        {
            cerr << "name_pipe creat fail... errno: " << errno << ",errstring: " << strerror(errno) << endl;
        }
    }
    ~FIFO()
    {
        int n = unlink(_path.c_str()); // 销毁，成功返回0
        if (n == 0)
        {
            cout << "name_pipe unlink success..." << endl;
        }
        else
        {
            cerr << "name_pipe unlink fail... errno: " << errno << ",errstring: " << strerror(errno) << endl;
            // 标准错误输出
        }
    }

private:
    string _path;
};

// 控制对管道的操作，借助管道的同步机制保护shm
class Sync
{
public:
    Sync()
        : rfd(-1), wfd(-1)
    {
    }
    void OpenRead() // 打开管道的读端
    {
        rfd = open(PAtH, O_RDONLY);
        if (rfd == -1)
        {
            cerr << "rfd open O_RDONLY fail... errno: " << errno << ",errstring: " << strerror(errno) << endl;
        }
        else
        {
            cout << "rfd open success" << "rfd=" << rfd << endl;
        }
    }
    void OpenWrite() // 打开管道的写端
    {
        wfd = open(PAtH, O_WRONLY);
        if (wfd == -1)
        {
            cerr << "wfd  open O_WRONLY fail... errno: " << errno << ",errstring: " << strerror(errno) << endl;
        }
        else
        {
            cout << "wfd open success" << "wfd=" << wfd << endl;
        }
    }
    bool wake() // 读端读，当读取结束或失败返回false
    {
        int c = 0;

        int n = read(rfd, &c, sizeof(c));
        if (n == sizeof(c))
            return true;
        if (n == 0)
        {
            cout << "client already close...,me too!" << endl;
            return false;
        }

        return false;
    }
    bool wakeup() // 写端写，当写入结束或失败返回false
    {
        int c = 0;

        int n = write(wfd, &c, sizeof(c));

        if (n == sizeof(c))
            return true;
        return false;
    }

private:
    int rfd;
    int wfd;
};